home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / drivers1.zip / HPPCLAN.ASM < prev    next >
Assembly Source File  |  1992-01-10  |  23KB  |  897 lines

  1. PAGE ,132
  2. version    equ    1
  3. ;History:74,1
  4.  
  5. ;  Russell Nelson, Clarkson University.
  6. ;  Copyright, 1988-1991, Russell Nelson
  7. ;  The following people have contributed to this code: David Horne, Eric
  8. ;  Henderson, and Bob Clements.
  9.  
  10. ;   This program is free software; you can redistribute it and/or modify
  11. ;   it under the terms of the GNU General Public License as published by
  12. ;   the Free Software Foundation, version 1.
  13. ;
  14. ;   This program is distributed in the hope that it will be useful,
  15. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;   GNU General Public License for more details.
  18. ;
  19. ;   You should have received a copy of the GNU General Public License
  20. ;   along with this program; if not, write to the Free Software
  21. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. ; Modified 910516 by Glenn Talbott, Hewlett-Packard Roseville Networks
  24. ; Division, to support the HP 27247A assembly number 27247-60002. This
  25. ; new version of the HP 27247A has a jumper which allows operation in PCs
  26. ; which violate the ISA specification for IOCHRDY by expecting the card
  27. ; to assert IOCHRDY early (actually before the card can fully decode the
  28. ; IO Address). This change does not affect this driver, however the following
  29. ; changes do.
  30. ;
  31. ; The card ID byte changes from 0x81 to 0x91.
  32. ;
  33. ; Added support for interrupt IRQ numbers 10 and 11.
  34. ;
  35. ; Comments in this code refer to 27247 rev 1.
  36.  
  37.     include    defs.asm
  38.  
  39. code    segment    word public
  40.     assume    cs:code, ds:code
  41.  
  42. ;*****************************************************************************
  43. ;
  44. ;    hppclan controller board offsets
  45. ;    IO port definition (BASE in io_addr)
  46. ;*****************************************************************************
  47. NE_DATAPORT    EQU    0ch        ; hppclan Port Window.
  48. HP_PROM        equ    00h
  49. HP_OPTION    equ    08h
  50. EN_OFF        equ    10h
  51.  
  52. ENDCFG_BM8    equ    48h
  53.  
  54. OPTION_RUN    equ    01h
  55. OPTION_DATA    equ    10h
  56.  
  57.     include    8390.inc
  58.  
  59. ; Shared memory management parameters
  60.  
  61. SM_TSTART_PG    EQU    0h        ; First page of TX buffer
  62. SM_RSTART_PG    EQU    6h        ; start at page 6
  63. ifndef debugxx
  64. SM_RSTOP_PG    EQU    80h        ; end at page 80
  65. ; add larger memory constant for 16 bit cards - gft - 910528
  66. SM_RSTOP_PG16    EQU    0FFh        ; end at page 0xff if 16 bit card
  67. else
  68. ; Make problems occur sooner and faster by having a smaller ring
  69. ; - gft - 910618
  70. SM_RSTOP_PG    EQU    1fh
  71. SM_RSTOP_PG16    EQU    1fh
  72. endif
  73.  
  74. ram_enable    macro
  75.     endm
  76.  
  77. mc_chan_on    macro
  78.     mov    al,chan_sel
  79.     mov    dx,96h
  80.     out    dx,al            ; select channel
  81.  
  82.     mov    dx,94h
  83.     mov    al,0a0h            
  84.     out    dx,al            ; protect system board
  85.  
  86.     mov    dx,102h            ; point dx at option reg
  87. endm
  88.  
  89. mc_chan_off    macro
  90.     mov    dx,96h
  91.     xor    al,al
  92.     out    dx,al
  93. endm
  94.  
  95. reset_8390    macro
  96.     local   is_mc_b
  97.     local    not_mc_c
  98.     local    not_mc_d
  99.  
  100.     test    sys_features,MICROCHANNEL
  101.     jne    is_mc_b
  102.     jmp    not_mc_c
  103. is_mc_b:
  104.     mc_chan_on
  105.     in    al,dx            ;capture and save option register
  106.     and    al, not OPTION_RUN    ;reset the 8390
  107.     out    dx,al
  108.     longpause
  109.     or    al, OPTION_RUN        ;turn it back on
  110.     out    dx,al        
  111.     mc_chan_off
  112.     loadport            ;Set DX the way we expect it
  113.     setport    HP_OPTION        
  114.     jmp    not_mc_d
  115.  
  116. not_mc_c:
  117.     loadport
  118.     setport    HP_OPTION        ;hard reset 8390.
  119.     xor    al,al            ;reset the 8390
  120.     out    dx,al
  121.     longpause
  122.  
  123. ; Revised int_no setting to use table lookup for 27247 rev 1
  124.  
  125.     push    bx        ;paranoia?
  126.     xor    bh,bh            ;clear high half of bx
  127.     mov    bl,int_no        ;get the index
  128.     add     bx,cs:int_bits        ;add the address of table
  129.                 ; the superfluous segment override prevents
  130.                 ; one of those #$%^&! phase errors in MASM
  131.     mov    al,byte ptr [bx]    ;properly adjusted bits for int_no
  132.     or    al, OPTION_RUN        ;turn it back on
  133.     out    dx,al        
  134.     pop    bx
  135.  
  136. not_mc_d:
  137.     endm
  138.  
  139. terminate_board    macro
  140.     local is_mc_a
  141.     local not_mc_a
  142.     local not_mc_b
  143.     test    sys_features,MICROCHANNEL
  144.     jne    is_mc_a
  145.     jmp    not_mc_a
  146.  
  147. is_mc_a:
  148. ; I can't believe this ever worked right, so it's probably not necessary
  149. ; to put the card into reset for a terminate. Never the less the 
  150. ; call to the mc_chan_on macro was missing from here - gft - 910529
  151. ;
  152. ; New comment: When I wrote the above 910529 comment I couldn't figure out
  153. ; how it ever worked, now I know; It never did. In a microchannel machine
  154. ; the system boots and the option register is set with the proper IRQ, I/O 
  155. ; address, and OPTION_RUN on by system initialization code. When we terminate
  156. ; the packet driver we leave the OPTION_RUN bit OFF. When the OPTION_RUN bit
  157. ; is OFF you can't read the station address from ROM, hence the code which
  158. ; identifies the card fails! Therefor you can't ever re-start the packet 
  159. ; driver after a terminate!
  160. ;
  161. ; To fix this, and leave the card in the same state as at bootup, I modified
  162. ; the below code to reset, then restore the option register for MCA machines.
  163. ;
  164. ; - gft - 910610
  165. ;
  166.     mc_chan_on
  167.     in    al,dx            ;capture and save option register
  168.     and    al, not OPTION_RUN    ;reset the 8390
  169.     out    dx,al
  170.     longpause
  171.     or    al, OPTION_RUN        ;turn the card back on for future access
  172.     out    dx,al
  173.     mc_chan_off
  174.     loadport            ;Set DX the way we expect it
  175.     setport    HP_OPTION        
  176.     jmp    not_mc_b
  177.  
  178. not_mc_a:
  179.     loadport
  180.     setport    HP_OPTION        ;hard reset 8390.
  181.     xor    al,al
  182.     out    dx,al
  183. not_mc_b:
  184.     endm
  185.  
  186.     extrn    sys_features: byte
  187.  
  188.     extrn    set_recv_isr: near
  189.  
  190. ;enter with si -> argument string, di -> word to store.
  191. ;if there is no number, don't change the number.
  192.     extrn    get_number: near
  193.  
  194. ;enter with dx -> name of word, di -> dword to print.
  195.     extrn    print_number: near
  196.  
  197. ;enter with al = single character
  198.     extrn    chrout: near
  199.  
  200.     public    int_no, io_addr
  201. int_no        db    3,0,0,0        ;must be four bytes long for get_number.
  202. io_addr        dw    0300h,0        ; I/O address for card (jumpers)
  203.  
  204.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  205. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  206. driver_type    db    ?        ;Wild card matches any type
  207. driver_name    db    "HP ",20 dup(?)    ;name of the driver.
  208. driver_function    db    2
  209. parameter_list    label    byte
  210.     db    1    ;major rev of packet driver
  211.     db    9    ;minor rev of packet driver
  212.     db    14    ;length of parameter list
  213.     db    EADDR_LEN    ;length of MAC-layer address
  214.     dw    GIANT    ;MTU, including MAC headers
  215.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  216.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  217.     dw    0    ;(# of successive xmits) - 1
  218. int_num    dw    0    ;Interrupt # to hook for post-EOI
  219.             ;processing, 0 == none,
  220.  
  221. is_186        db    0
  222.  
  223. chan_sel    db    0    ;Channel select for MICROCHANNEL machines
  224.  
  225. ;
  226. ;    Special case Block input routine. Used on extra memory
  227. ;    space for board ID etc. DMA count is set X2,
  228. ;    CX = byte count, es:si = buffer location, ax = buffer address
  229. ;
  230. sp_block_input:
  231. ;    Nothing special needed for hppclan
  232. ;
  233. ;    Block input routine
  234. ;    CX = byte count, es:si = buffer location, ax = buffer address
  235.  
  236.     public    block_input
  237. block_input:
  238.     push    ax            ; save buffer address
  239.  
  240.     loadport
  241.     setport    HP_OPTION        
  242.     test    sys_features,MICROCHANNEL
  243.     je    not_mc_1
  244.     jmp    is_mc_1
  245. not_mc_1:
  246.     in    al,dx
  247.     or    al,OPTION_DATA        ;Enable the data port except on MCA
  248.     out    dx,al
  249.  
  250. is_mc_1:
  251.     setport EN_CCMD
  252.     pause_
  253.     mov    al,ENC_NODMA+ENC_PAGE0+ENC_START
  254.     out    dx,al
  255.     setport    EN0_RCNTLO    ; remote byte count 0
  256.     pause_
  257.     mov    al,cl
  258.     out    dx,al
  259.     setport    EN0_RCNTHI
  260.     pause_
  261.     mov    al,ch
  262.     out    dx,al
  263.     pop    ax        ; get our page back
  264.     setport    EN0_RSARLO
  265.     pause_
  266.     out    dx,al        ; set as hi address
  267.     setport    EN0_RSARHI
  268.     pause_
  269.     mov    al,ah
  270.     out    dx,al
  271.     setport EN_CCMD
  272.     pause_
  273.     mov    al,ENC_RREAD+ENC_START    ; read and start
  274.     out    dx,al
  275.     setport    NE_DATAPORT
  276.     pause_
  277.     cmp    is_186,0
  278.     jnz    read_186
  279.     shr    cx,1
  280. read_loop:
  281.     in    ax,dx        ; get a word
  282.     stosw            ; save it
  283.     loop    read_loop
  284.     jnc    read_done
  285.     in    al,dx
  286.     stosb
  287.     jmp    short read_done
  288. read_186:
  289.     shr    cx,1
  290.     db    0f3h, 06dh    ;masm 4.0 doesn't grok "rep insw"
  291.     jnc    read_done
  292.     db    06ch        ;masm 4.0 doesn't grok "insb"
  293. read_done:
  294.     setport    HP_OPTION
  295.     test    sys_features,MICROCHANNEL
  296.     je    not_mc_2
  297.     ret
  298. not_mc_2:
  299.     in    al,dx
  300.     and    al,not OPTION_DATA
  301.     out    dx,al
  302.     ret
  303. ;
  304. ;    Block output routine
  305. ;    CX = byte count, ds:si = buffer location, ax = buffer address
  306.  
  307.  
  308. block_output:
  309.     assume    ds:nothing
  310.     push    ax        ; save buffer address
  311.  
  312.     loadport
  313.     setport    HP_OPTION
  314.     test    sys_features,MICROCHANNEL
  315.     je    not_mc_3
  316.     jmp    is_mc_3
  317. not_mc_3:
  318.     in    al,dx
  319.     or    al,OPTION_DATA    ; enable the data port except on MCA
  320.     out    dx,al
  321.  
  322. is_mc_3:
  323.     inc    cx        ; make even
  324.     and    cx,0fffeh
  325.     setport EN_CCMD
  326.     pause_
  327.     mov    al,ENC_NODMA+ENC_START
  328.     out    dx,al        ; stop & clear the chip
  329.  
  330. ; To quote from the National DP8390 Datasheet Addendum, June 1990
  331. ;
  332. ;   11.0 Remote DMA Write
  333. ;
  334. ;   Under certain conditions the NIC may issue /MWR and /PRD before
  335. ;   PRQ for the first DMA transfer. This causes an extraneous byte to be
  336. ;   written inot memory at the first Remote DMA Write location. [...]
  337. ;
  338. ;   To prevent this condition, write a non-zero value into RBCR0 and 
  339. ;   issued [sic] the Remote Read DMA command to the NIC (CR=0AH), but
  340. ;   do not give any Read Acknowledges (/RACK). (This causes PRQ to go high.)
  341. ;   Then write the desired byte count into RBCR0 and RBCR1 and give the 
  342. ;   Remote Write DMA command (CR=12H). The Remote Write DMA will operate as
  343. ;   normal.
  344. ;
  345. ; My interpretation of the above is          - gft - 910603
  346.  
  347.     
  348.     setport    EN0_RCNTLO    ; remote byte count 0
  349.     pause_
  350.     mov    al,0ffh        ; a non-zero value
  351.     out    dx,al
  352.     setport EN_CCMD
  353.     pause_
  354.     mov     al,ENC_RREAD+ENC_START ; read and start
  355.     out     dx,al        ; starts the read setting PRQ for the first
  356.                 ; DMA transfer, now reprogram everything
  357.                 ; and start a write instead.
  358.  
  359. ;
  360. ; BUT WHAT THE NATIONAL DOCUMENTATION DOESN'T TELL YOU ...
  361. ;
  362. ;  When the read is started, the remote byte count register is decremented
  363. ;  (in this case from 0ffh to 0feh). This takes a finite amount of time. 
  364. ;  IF you are TOO QUICK in re-programming the remote byte count 0 register
  365. ;  to the correct value, the NEW VALUE GETS DECREMENTED INSTEAD! Then when
  366. ;  you reach the last byte of the buffer and you output it to the IO port,
  367. ;  the NIC has already reached a count of zero and WON'T HANDSHAKE THE LAST
  368. ;  BYTE!. Result, computer HUNG, powercycle to recover. Therefore a stall is 
  369. ;  required here, I use at least 1.5uS
  370. ;                                      - gft - 910603
  371. ;
  372.     in    al,61h        ; read from NMI Status register for IO delay
  373.     in    al,61h        ; ~ 0.5uS on Microchannel and ~ 1.0 on ISA
  374.     in    al,61h        ; for a total of ~1.5uS or 3.0uS.
  375.  
  376. ; we now return you to your regularly scheduled block_output routine.
  377.  
  378.     setport    EN0_RCNTLO    ; remote byte count 0
  379.     pause_
  380.     mov    al,cl
  381.     out    dx,al
  382.     setport    EN0_RCNTHI
  383.     pause_
  384.     mov    al,ch
  385.     out    dx,al
  386.     pop    ax        ; get our page back
  387.     setport    EN0_RSARLO
  388.     pause_
  389.     out    dx,al        ; set as lo address
  390.     setport    EN0_RSARHI
  391.     pause_
  392.     mov    al,ah
  393.     out    dx,al
  394.     setport EN_CCMD
  395.     pause_
  396.     mov    al,ENC_RWRITE+ENC_START    ; write and start
  397.     out    dx,al
  398.     setport    NE_DATAPORT
  399.     pause_
  400.     shr    cx,1
  401.     cmp    is_186,0
  402.     jnz    write_186
  403. write_loop:
  404.     lodsw            ; get a word
  405.     out    dx,ax        ; save it
  406.     loop    write_loop
  407.     jmp    short write_done
  408. write_186:
  409.     db    0f3h, 06fh        ;masm 4.0 doesn't grok "rep outsw"
  410. write_done:
  411.     mov    cx,0
  412.     setport    EN0_ISR
  413. tx_check_rdc:
  414.     in    al,dx
  415.     test    al,ENISR_RDC    ; dma done ???
  416.     clc
  417.     jnz    tx_start
  418.     loop    tx_check_rdc
  419.     stc
  420. tx_start:
  421.     setport    HP_OPTION
  422.     test    sys_features,MICROCHANNEL
  423.     je    not_mc_4
  424.     ret
  425. not_mc_4:
  426.     lahf                ;save cy.
  427.     in    al,dx
  428.     and    al,not OPTION_DATA
  429.     out    dx,al
  430.     sahf                ;restore cy.
  431.     ret
  432.  
  433.     include    8390.asm
  434.  
  435.     public    usage_msg
  436. usage_msg    db    "usage: hppclan [-n] [-d] [-w] <packet_int_no> [<int_no> [<io_addr>]]",CR,LF
  437.  
  438.     public    copyright_msg
  439. copyright_msg    db    "Packet driver for HP PC LAN cards, version "
  440.         db    '0'+majver,".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
  441.  
  442. no_hp_msg    db    "No HP PC LAN card found (matching io_addr or int_no if spedified).",CR,LF,'$'
  443. cfg_err_msg    db    "Configuration failed. Check parameters.",CR,LF,'$'
  444. int_no_name    db    "Interrupt number ",'$'
  445. io_addr_name    db    "I/O port ",'$'
  446.  
  447. comment \
  448.  
  449. Here are the ID byte values for all released cards.  Bit 7 of the ID byte
  450. for AT cards indicates bus width (as well as RAM buffer size).
  451.  
  452. The ID byte was added to give a unique number to every revision of every card
  453. produced.  However, it is a little more than just a flat assignment; there is
  454. some fields.  For driver software it is assumed the driver knows what bus it
  455. is on (eg. AT verses MC):
  456.  
  457. The format of the ID byte (offset 0x07 from I/O base) is:
  458.  
  459.         7  6  5  4  3  2  1  0
  460.         a  b  b  b  c  c  c  c
  461. where,
  462.         "a"   is the AT bus width bit
  463.          0 =  8 bit AT cards (32K bytes of buffer RAM)
  464.          1 = 16 bit AT cards (64K bytes of buffer RAM)
  465.  
  466.         "bbb" is for board revisions
  467.  
  468.         "ccc" is the LAN Media type
  469.          000 = HP StarLAN-10
  470.          001 = 10-Base-T (Ethertwist)
  471.          002 = 10-Base-2 (ThinLAN)
  472.          ??? = reserved for future
  473.  
  474. The current ID bytes assigned are:
  475.         0x00 = (obsolete) HP27240 AT8  StarLAN
  476.         0x10 = (obsolete) HP24240 AT8  StarLAN rev B
  477.         0x00 = (obsolete) HP27241 MC16 StarLAN
  478.         0x01 = HP27245 AT8  10-Base-T
  479.         0x01 = HP27246 MC16 10-Base-T
  480.         0x02 = HP27250 AT8  ThinLAN
  481.         0x81 = HP27247 AT16 10-Base-T
  482.         0x91 = HP27247 AT16 10-Base-T rev 1
  483.  
  484. NOTE:   All Microchannel cards are 16 bits wide.
  485.         All 8 bit cards have 32K bytes of buffer RAM.
  486.         All 16 bit cards (AT & MC) have 64K bytes of buffer RAM.
  487. \
  488.  
  489. this_board_msg    db    "This board is an HP",'$'
  490.  
  491. ISA_name_list    dw    board_00ISA, board_10, board_01ISA, board_02, board_81
  492.         dw    board_91
  493.         dw    board_unk
  494. MCA_name_list    dw    board_00MCA, board_01MCA
  495.         dw    board_unk
  496.  
  497. board_00ISA    db    00h, "27240",0,60    ;AT8  StarLAN
  498. board_10    db    10h, "24240",0,60    ;AT8  StarLAN rev B
  499. board_00MCA    db    00h, "27241",0,60    ;MC16 StarLAN
  500. board_01ISA    db    01h, "27245",0,60    ;AT8  10-Base-T
  501. board_01MCA    db    01h, "27246",0,60    ;MC16 10-Base-T
  502. board_02    db    02h, "27250",0,60    ;AT8  ThinLAN
  503. board_81    db    81h, "27247",0,60    ;AT16 10-Base-T
  504. board_91    db    91h, "27247",0,60    ;AT16 10-Base-T rev 1
  505. board_unk    db    -1h, "Unknown HP272xx",0,60    ;just a guess.
  506.  
  507. ; ISA DEFAULTS for io_addr and int_no,
  508. ; MCA DEFAULTS to first found.
  509.  
  510. DEF_IO_ADDR    equ    0300h    
  511. DEF_INT_NO    equ    3
  512.  
  513. MC_DEF_IO    equ    1
  514. MC_DEF_INT    equ    2
  515. MC_DEF_BOTH    equ    MC_DEF_IO+MC_DEF_INT
  516.  
  517. mc_def_req    db    0
  518.  
  519. int_no_table    db    3, 4, 5, 7, 9, 10, 11, 12
  520.  
  521. ; Added for 27247 rev 1, interrupt numbers are no longer simply left shifted
  522. ; one for writing into the option register. Use a lookup table instead.
  523. ; Entries of 0xff are not valid for the card.
  524.  
  525. ; Table for AT cards except 27247 rev 1
  526.  
  527. int_bits_0    db    0ffh, 0ffh, 04h, 06h, 08h, 0ah, 0ffh, 0eh ;ints 0-7
  528.         db    0ffh, 04h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ;ints 8-f
  529.  
  530. ; Table for 27247 rev 1
  531.  
  532. int_bits_1    db    0ffh, 0ffh, 04h, 06h, 08h, 0ah, 0ffh, 0eh ;ints 0-7
  533.         db    0ffh, 04h, 02h, 0ch, 0ffh, 0ffh, 0ffh, 0ffh ;ints 8-f
  534.  
  535. int_bits    dw int_bits_0
  536.  
  537. ; First 3 bytes of the LAN Addres will identify the board as HP
  538.  
  539. hp_vendor_id    db    08h,00h,09h
  540.  
  541.     public    parse_args
  542. parse_args:
  543. ;exit with nc if all went well, cy otherwise.
  544.     test    sys_features,MICROCHANNEL
  545.     jne    parse_args_mc
  546.     jmp    parse_args_1
  547.  
  548. parse_args_mc:
  549.  
  550. ; first determine if non-default values have been requested
  551. ; get_number will return requested value, -1, or carry flag set
  552.  
  553.     mov    di,offset int_no
  554.     call    get_number
  555.     mov    BYTE PTR [di+1], 0
  556.     mov    WORD PTR [di+2], 0
  557.     jnc    parse_args_mc2
  558.     mov    BYTE PTR [di], 0ffh    ; error return, use -1 value
  559.  
  560. parse_args_mc2:
  561.     mov    di,offset io_addr
  562.     call    get_number
  563.     mov    WORD PTR [di+2], 0
  564.     jnc    parse_args_mc3
  565.     mov    WORD PTR [di], 0ffffh    ; error return, use -1 value
  566.  
  567. parse_args_mc3:
  568.     
  569.     xor    al,al
  570.     cmp    io_addr,0ffffh
  571.     jne    parse_args_mc4
  572.     mov    al,MC_DEF_IO
  573.  
  574. parse_args_mc4:
  575.     cmp    int_no,0ffh
  576.     jne    parse_args_mc5
  577.     or    al,MC_DEF_INT
  578.  
  579. parse_args_mc5:
  580.     mov    mc_def_req,al
  581.  
  582. ;The following code to read the POS registers is courtesy of Racal-Interlan.
  583.  
  584. ; channel selector resides at io 96h
  585. ; POS register base is at io 100h
  586.  
  587. ; search thro' the slots for a 9210 card
  588.     mov    cx, 8            ; for all channels(slots)
  589.  
  590. ; channel select value for slots 0,1,2.. is 8,9,A etc
  591. ; start with slot 0, and then 7,6,5,4,3,2,1
  592.  
  593. get_01:
  594.     mov    ax, cx            ; channel number
  595.     or    ax, 08h            ; reg. select value
  596.     mov    chan_sel,al        ; save each one, the LAST will right
  597.     mov    dx, 96h            ; channel select register
  598.     out    dx, al            ; select channel
  599.  
  600.     mov    dx, 94h            ; protect system board
  601.     mov    al, 0a0h
  602.     out    dx, al            
  603.  
  604. ; read adapter id
  605.     mov    dx, 100h
  606.     in    al, dx            ; adapter id - ms byte
  607.     mov    ah, al
  608.     inc    dx
  609.     in    al, dx            ; adapter id - ls byte
  610.  
  611. ; Check if HP
  612.     cmp    ax, 0ca63h
  613.     je    get_03
  614.     
  615. get_02:
  616.     ; come back to here if card found does not match user 
  617.     ; requirements below
  618.  
  619.     loop    get_01
  620.  
  621.     mc_chan_off
  622.     mov    dx,offset no_hp_msg
  623.     jmp    error
  624.  
  625. get_03:        ; found an HP adapter, is it the right one?
  626.  
  627. comment \
  628.  
  629. The only POS registers defined for the Microchannel card (HP27246) are:
  630.  
  631.         0x100 = Adapter Identification LSB (0xCA) Read only
  632.         0x101 = Adapter Identification MSB (0x63) Read only
  633.         0x102 = Option Register Read/Write
  634.  
  635. The Option register bits are defined as:
  636.  
  637.         7 6 5 4 3 2 1 0
  638.         a a a - b b b c
  639.  
  640. where,
  641.         "aaa" is the I/O Base Address Relocation bits
  642.          000 = 0x0400 to 0x041f
  643.          001 = 0x1400 to 0x141f
  644.          010 = 0x2400 to 0x241f
  645.          011 = 0x3400 to 0x341f
  646.          100 = 0x4400 to 0x441f
  647.          101 = 0x5400 to 0x541f
  648.          110 = 0x6400 to 0x641f
  649.          111 = 0x7400 to 0x741f
  650.  
  651.  
  652.         "bbb" is the Interrupt Level bits
  653.          000 = INT 3
  654.          001 = INT 4
  655.          010 = INT 5
  656.          011 = INT 7
  657.          100 = INT 9
  658.          101 = INT 10
  659.          110 = INT 11
  660.          111 = INT 12
  661.  
  662.         "c" is the Card Enable / NIC Reset bit
  663.          0 = NIC held in reset (eg. cannot access its registers)
  664.          1 = NIC not reset (eg. regster can be accessed)
  665.          NOTE: Access to the PROM should only occur while NIC is held in reset.
  666.  
  667. \
  668.  
  669.     mov    dx,102h
  670.     in    al,dx
  671.     and    ax,00e0h        ;leave only the base address bits
  672.     push    cx
  673.     mov    cl,12-5            ;now ends at bit 5, should end at bit 12
  674.     shl    ax,cl
  675.     pop    cx
  676.     or    ax,400h
  677.     mov    di,ax        ; temporary save
  678.  
  679.     in    al,dx
  680.     shr    al,1
  681.     and    al,7
  682.     mov    bl,al
  683.     xor    bh,bh
  684.     mov    al,int_no_table[bx]
  685.  
  686.     ; check for matches with user selects
  687.  
  688.     mov    ah,mc_def_req
  689.     test    ah,MC_DEF_IO
  690.     jz    get_04
  691.     mov    io_addr,di    ; user wants default, copy temp address
  692.  
  693. get_04:
  694.     test    ah,MC_DEF_INT
  695.     jz    get_05
  696.     mov    int_no,al    ; user wants default, copy temp int number
  697.  
  698. get_05:    
  699.     cmp    di,io_addr
  700.     je     get_06
  701.     jmp    get_02        ; correct io_addr not found, keep looking
  702.  
  703. get_06:    
  704.     cmp    al,int_no
  705.     je     get_07
  706.     jmp    get_02        ; correct io_addr not found, keep looking
  707.  
  708. get_07:        ; if we get here we now have the io_addr and int_no
  709.         ; that the user wanted
  710.     mc_chan_off
  711.     jmp parse_args_5
  712.  
  713. ;
  714. ; Much simpler code for ISA machine parse_args
  715. ;
  716. parse_args_1:
  717.     mov    di,offset int_no
  718.     call    get_number
  719.     jc    parse_args_2
  720.     cmp    WORD PTR [di],0
  721.     jl    parse_args_2
  722.     jmp    parse_args_3
  723.  
  724. parse_args_2:
  725.     mov    WORD PTR [di],DEF_INT_NO
  726.     mov    WORD PTR [di+2],0
  727.  
  728. parse_args_3:
  729.     mov    di,offset io_addr
  730.     call    get_number
  731.     jc    parse_args_4
  732.     cmp    WORD PTR [di],0
  733.     jl    parse_args_4
  734.     jmp    parse_args_5
  735.  
  736. parse_args_4:
  737.     mov    WORD PTR [di],DEF_IO_ADDR
  738.     mov    WORD PTR [di+2],0
  739.  
  740. parse_args_5:    ;Finally verify HP Vendor ID in 1st 3 bytes of station addr
  741.     loadport
  742.     setport    HP_PROM
  743.     mov    di,offset hp_vendor_id
  744.     mov    cx,3
  745. id_card_loop:
  746.     in    al,dx
  747.     cmp    al, BYTE PTR [di]
  748.     je    id_card_loop1
  749.     mov    dx,offset no_hp_msg
  750.     jmp    error
  751.  
  752. id_card_loop1:
  753.     inc    di
  754.     inc    dx
  755.     loop    id_card_loop
  756.  
  757. ; for 27247 rev 1, delete the next two instructions to allow inline execution
  758. ; of id_card
  759. ;    clc
  760. ;    ret
  761.  
  762.  
  763. ; for 27247 rev 1, changed this routine from "init_card" to "id_card" and 
  764. ; called it from parse_args to verify argument int_no and print out all
  765. ; the driver name. This allows full verification of int_no before init_card
  766. ; is called. init card then becomes a big NOP, but must be declared so that it
  767. ; can be called from 8390.asm
  768.  
  769. id_card:
  770. ;Read PROM contents
  771.     loadport
  772.     setport    HP_PROM
  773.     mov    di,offset curr_hw_addr
  774.     mov    ax,cs
  775.     mov    es,ax
  776.     mov    cx,EADDR_LEN
  777.     xor    ah,ah
  778. id_card_1:
  779.     in    al,dx
  780.     add    ah,al
  781.     inc    dx
  782.     stosb
  783.     loop    id_card_1
  784.     in    al,dx            ;now get the checksum.
  785.     xor    ah,al            ;add it in.
  786.     cmp    ah,-1            ;now it should have all ones set.
  787. ;ugh.  The checksum was botched on some boards, so we can't use it.
  788. ;    jne    id_card_2        ;did it match?  Nope, return error.
  789.     inc    dx
  790.     in    al,dx            ;get the hardware revision number.
  791.  
  792.     test    sys_features,MICROCHANNEL    ;ISA or MCA?
  793.     jne    is_16bit        ;MCA - all MCA cards are 16-bit cards.
  794.     test    al,80h            ;16-bit system?
  795.     je    check_16bit
  796.  
  797. ; Only AT 16 bit cards get here, check for extended IRQ support on 27247 rev 1
  798.  
  799.     cmp    al,91h
  800.     jne    is_16bit
  801.     mov    bx, offset int_bits_1
  802.     mov    int_bits,bx
  803.  
  804. is_16bit:
  805.     or    endcfg,ENDCFG_WTS    ;yes, use word transfer mode.
  806.  
  807. ; also use larger on-card memory for 16 bit -gft 910528
  808.  
  809.     mov    sm_rstop_ptr,SM_RSTOP_PG16
  810.  
  811. check_16bit:
  812.  
  813.     mov    bx,offset MCA_name_list        ;assume MCA
  814.     test    sys_features,MICROCHANNEL    ;ISA or MCA?
  815.     jne    check_board_name        ;MCA.
  816.  
  817. ; ISA board here, verify interrupt value parameter, added for 27247 rev 1
  818.  
  819.     xor    bh,bh            ; clear hi half of bx
  820.     mov    bl,int_no        ; index to the interrupt number
  821.     add    bx,int_bits        ; get pointer to proper int_bits table
  822.     cmp    byte ptr [bx],-1    ; check for not valid
  823.     jne    check_board_ISA_name    ; int_no OK
  824.     mov    dx, offset cfg_err_msg    ; int_no not valid, tough luck
  825. error:
  826.     mov    ah,9        ; Type the msg
  827.     int    21h
  828.     stc            ; Indicate error
  829.     ret            ; Return to common code
  830.  
  831. check_board_ISA_name:
  832.     mov    bx,offset ISA_name_list        ;Get the ISA name list now
  833. check_board_name:
  834.     push    si        ; for 27247 rev 1, save si
  835. check_board_name_loop:
  836.     mov    si,[bx]            ;get a pointer to a string.
  837.     add    bx,2
  838.     cmp    byte ptr [si],-1    ;is this the end?
  839.     je    check_board_found
  840.     cmp    al,[si]            ;is this the right one?
  841.     jne    check_board_name_loop
  842. check_board_found:
  843.     inc    si            ;skip the board revision number.
  844.  
  845.     mov    dx,offset this_board_msg
  846.     mov    ah,9
  847.     int    21h
  848.  
  849.     mov    ax,ds            ;copy the driver name to where
  850.     mov    es,ax            ;  we need it.
  851.     mov    di,offset driver_name+3
  852. check_board_copy:
  853.     lodsb
  854.     stosb
  855.     or    al,al
  856.     je    check_board_done_print
  857.     call    chrout            ;print the character.
  858.     jmp    check_board_copy
  859. check_board_done_print:
  860.     lodsb                ;copy the driver type number over
  861.     mov    driver_type,al
  862.     pop    si        ; for 27247 rev 1, restore si for caller
  863.     mov    al,CR
  864.     call    chrout
  865.     mov    al,LF
  866.     call    chrout
  867.  
  868.     clc
  869.     ret
  870. id_card_2:
  871.     stc
  872.     ret
  873.  
  874. ; for 27247 rev 1, new init_card: the big NOP
  875.  
  876.     extrn    etopen_diagn: byte
  877.  
  878. init_card:
  879.     clc
  880.     ret
  881.  
  882.  
  883.     public    print_parameters
  884. print_parameters:
  885. ;echo our command-line parameters
  886.     mov    di,offset int_no
  887.     mov    dx,offset int_no_name
  888.     call    print_number
  889.     mov    di,offset io_addr
  890.     mov    dx,offset io_addr_name
  891.     call    print_number
  892.     ret
  893.  
  894. code    ends
  895.  
  896.     end
  897.